﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using AAA.DesignPattern.Observer;
using AAA.Meta.Chart.Data;
using AAA.Base.Util.Graphic;

namespace AAA.TeeChart
{
    public partial class SignalLightPane : UserControl, IObserver
    {
        private List<string> _lstTitle;

        private Dictionary<string, string> _dicSignal; //Title <=> Signal
        private Dictionary<string, Color> _dicLightMapping; // Signal <=> Color
        
        private int _iSignalLightCount;
        private object _oDisplayKey;

        private Color _cBorderColor = Color.Black;

        private int _iTopPad = 3;
        private int _iBottomPad = 3;
        private int _iLeftPad = 3;
        private int _iRightPad = 3;
        private int _iPad = 3;

        public int Pad
        {
            get { return _iPad; }
            set { _iPad = value; }
        }

        public Color BorderColor
        {
            get { return _cBorderColor; }
            set { _cBorderColor = value; }
        }

        public int TopPad
        {
            get { return _iTopPad; }
            set { _iTopPad = value; }
        }
        
        public int BottomPad
        {
            get { return _iBottomPad; }
            set { _iBottomPad = value; }
        }
        
        public int LeftPad
        {
            get { return _iLeftPad; }
            set { _iLeftPad = value; }
        }
        
        public int RightPad
        {
            get { return _iRightPad; }
            set { _iRightPad = value; }
        }

        public object DisplayKey
        {
            get { return _oDisplayKey; }
            set { _oDisplayKey = value; }
        }

        public SignalLightPane()
        {
            InitializeComponent();
            _lstTitle = new List<string>();
            _dicSignal = new Dictionary<string, string>();
            _dicLightMapping = new Dictionary<string, Color>();
            _iSignalLightCount = 0;
            MessageSubject.Instance().Subject.Attach(this);
            Paint += new PaintEventHandler(OnPaint);
        }

        void OnPaint(object sender, PaintEventArgs e)
        {
            Draw();
        }

        public void AddTitle(string strTitle)
        {
            if (_lstTitle.IndexOf(strTitle) < 0)
            {
                _lstTitle.Add(strTitle);
                _dicSignal.Add(strTitle, "");
            }
        }

        public void AddColorMapping(string strLabel, Color cColor)
        {
            if (_dicLightMapping.ContainsKey(strLabel))
                _dicLightMapping[strLabel] = cColor;
            else
                _dicLightMapping.Add(strLabel, cColor);                    
        }

        public void AddSignal(string strTitle, string strSignal)
        {
            if (_dicSignal.ContainsKey(strTitle))
                _dicSignal[strTitle] = strSignal;
        }

        private void DrawBorder(Graphics g)
        {
            int iWidth = ClientSize.Width;
            int iHeight = ClientSize.Height;
            try
            {
                g.DrawRectangle(new Pen(new SolidBrush(BorderColor), 1), new Rectangle(TopPad, LeftPad, iWidth - LeftPad - RightPad, iHeight - TopPad - BottomPad));
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + "," + ex.StackTrace);
            }
        }

        private void DrawLight(Graphics g)
        {
            if ((_dicSignal == null) || (_dicLightMapping == null) || (DisplayKey == null))
                return;

            int iInterval;
            int iWidth;
            int iRadius;
            Font font;
            StringFormat stringFormat = new StringFormat();
            string strMaxTitle = "";

            try
            {
                for (int i = 0; i < _lstTitle.Count; i++)
                {
                    if (_lstTitle[i].Length > strMaxTitle.Length)
                        strMaxTitle = _lstTitle[i];
                }

                iWidth = (int)((double)(Width - LeftPad - RightPad) / ((double)_dicSignal.Count));
                iRadius = (int)Math.Min(iWidth, Height - TopPad - BottomPad);
                iInterval = (int)(iWidth - iRadius) / 2;


                font = FontUtil.CreateFont(g, "新細明體", FontStyle.Regular, strMaxTitle, iRadius, iRadius);
                stringFormat.Alignment = StringAlignment.Center;
                stringFormat.LineAlignment = StringAlignment.Center;
                

                for(int i = 0; i < _lstTitle.Count; i++)
                {
                    if ((_dicSignal.ContainsKey(_lstTitle[i]) == false))
                        continue;                    
                    
                    if(_dicLightMapping.ContainsKey(_dicSignal[_lstTitle[i]]) == false)
                        continue;

                    g.FillEllipse(new SolidBrush(_dicLightMapping[_dicSignal[_lstTitle[i]]]), LeftPad + iWidth * i + iInterval, TopPad, iRadius, iRadius);
                    
                    g.DrawString(_lstTitle[i], 
                                 font, 
                                 new SolidBrush(Color.Black), 
                                 new RectangleF(LeftPad + iWidth * i, TopPad, iWidth, iRadius),
                                 stringFormat);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + "," + ex.StackTrace);
            }
        }

        public void Draw()
        {
            try
            {
                Graphics g = CreateGraphics();

                DrawBorder(g);
                DrawLight(g);

                g.Dispose();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + "," + ex.StackTrace);
            }
        }

        #region IObserver Members

        public void Update(object oSource, IMessageInfo miMessage)
        {
            List<object> lstMessage;
            List<string> lstTitle;
            List<object> lstSignal;
            int iPoint;
            Dictionary<string, BarDataExtra> dicBarDataExtra;



            try
            {
                if (miMessage.MessageSubject != "CursorPositionChanged")
                    return;

                lstMessage = (List<object>)miMessage.Message;

                iPoint = (int)lstMessage[0];
                dicBarDataExtra = (Dictionary<string, BarDataExtra>)lstMessage[1];

                if (dicBarDataExtra.ContainsKey((string)DisplayKey) == false)
                    return;
                lstSignal = dicBarDataExtra[(string)DisplayKey].GetInfo(iPoint);
                lstTitle = dicBarDataExtra[(string)DisplayKey].GetTitle();

                for (int i = 0; i < lstTitle.Count; i++)              
                    AddSignal(lstTitle[i], (string)lstSignal[i]);                

                Draw();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + "," + ex.StackTrace);
            }
        }

        #endregion
    }
}
